package com.broadtext.message.service.impl;

import com.broadtext.common.exp.DaoException;
import com.broadtext.common.repository.EntityDao;
import com.broadtext.common.service.impl.EntityServiceImpl;
import com.broadtext.common.utils.DateUtils;
import com.broadtext.common.utils.StringUtils;
import com.broadtext.message.model.EmailParam;
import com.broadtext.message.model.TtAlert;
import com.broadtext.message.service.IEmailService;
import com.broadtext.rms.system.model.SysUser;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;
import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service("emailService")
public class EmailServiceImpl extends EntityServiceImpl<TtAlert>  implements IEmailService{

    private static final Logger logger = LoggerFactory.getLogger(SmsServiceImpl.class);

    @Autowired
    @Qualifier("mailSender")
    private JavaMailSender mailSender;

    @Autowired
    @Qualifier("freeMarkerConfigurer")
    private FreeMarkerConfigurer freeMarkerConfigurer;

    @Value("${email.username}")
    private String emailUsername;

    /**
     *
     * <p>Description: 基类dao</p>
     * @param entityDao 基类实体dao
     */
    @Autowired
    @Qualifier("ttAlertDao")
    public void setEntityDao(EntityDao<TtAlert> entityDao) {
        super.entityDao = entityDao;
    }



    @Override
    @SuppressWarnings("unchecked")
    public void sendEmail() throws MessagingException, DaoException {
        //获取结转时间
        //第一步:查询上次发送时间
        String gatherTimeStart = this.getTasktime("email");
        Map<String, Object> params = new HashMap<>();
        params.put("gatherTimeStart", gatherTimeStart);
        //获取当前时间
        String gatherTimeEnd = DateUtils.getCurrentTime();
        params.put("gatherTimeEnd", gatherTimeEnd);
        List<TtAlert> list = this.entityDao.findByProperty("com.broadtext.message.model.TtAlert.getSendEmailAlert",params);
        Date now = new Date();
        //获取当前时间
        SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss");
        String time = format.format(now).substring(0,5);
        String week = DateUtils.getWeek(now);
        Map<String, Object> queryUserParams = new HashMap<>();
        queryUserParams.put("now",time);
        queryUserParams.put("week",week);
        logger.info(">>>>>>>now time :[week {}-{}]<<<<<<<",week,time);
        /*循环嵌套，实在不妥*/
        for (TtAlert alert : list) {
            if (StringUtils.isBlank(alert.getPackCode())||StringUtils.isBlank(alert.getAlertCode())) {
                continue;
            }
            queryUserParams.put("packCode",alert.getPackCode());
            queryUserParams.put("alertCode",alert.getAlertCode());
            //第三步:根据电池packCode 查询电池所属厂商下的所有的用户以及pack生产厂下的所有用户，且符合接受通知条件的人
            List<SysUser> userList = this.entityDao.findByProperty("com.broadtext.message.model.TtAlert.getEmailNoticeUser",queryUserParams);
            SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            for (SysUser user:userList) {
                //循环中try catch ，避免一条发送出错，后续全部不执行
                //其实不合理，异步通知应该用消息队列模型来做，无论是可靠性还是以后的扩展性mq都更合适
                //第四步:发送邮件
                if(StringUtils.isBlank(user.getEmail()))
                    continue;
                MimeMessage mailMsg = this.mailSender.createMimeMessage();
                MimeMessageHelper messageHelper = new MimeMessageHelper(mailMsg,
                        true, "UTF-8");
                messageHelper.setFrom(emailUsername);// 发送邮箱
                messageHelper.setTo(user.getEmail());// 接收邮箱
                messageHelper.setSentDate(new Date());// 发送时间
                messageHelper.setSubject("电池"+alert.getPackCode()+"出现"+alert.getLevelName()+alert.getAlertName()+"，请去查看");// 邮件标题

                EmailParam emailParam = new EmailParam();
                emailParam.setPackCode(alert.getPackCode());
                emailParam.setColClientId(alert.getColClientId());
                emailParam.setCusName(alert.getCusName());
                emailParam.setAlertName(alert.getAlertName());
                emailParam.setTruename(user.getTruename());
                emailParam.setLevelName(alert.getLevelName());
                emailParam.setPackModel(alert.getPackModel());
                emailParam.setHappenTime(f.format(alert.getHappenTimeStart()));

                // true 表示启动HTML格式的邮件
                try {
                    messageHelper.setText(this.getMailText(emailParam), true);// 邮件内容
                    this.mailSender.send(mailMsg);// 发送
                    logger.info(">>>>>>send mail to user[{}]",user.getTruename());
                } catch (Exception e) {
                    e.printStackTrace();
                    logger.info(">>>>>>send mail to user[{}] error",user.getTruename());
                }

                //TODO 插入发送记录到数据库
            }
        }

        //更新时间
        updateTaskTime("email",gatherTimeEnd);
    }


    /**
     * <p>Description: 查询结转时间</p>
     *
     * @param type 类型
     * @return string
     * @throws DaoException dao层异常
     */
    @SuppressWarnings("unchecked")
    private String getTasktime(String type) throws DaoException {
        String time = "";
        Map<String, Object> params = new HashMap<>();
        params.put("type", type);
        List<Map<String, Object>> list = this.entityDao.findByProperty("com.broadtext.message.model.SysMessage.getTasktime", params);
        if (list != null && list.size() > 0 && list.get(0) != null) {
            time = String.valueOf(list.get(0).get("gatherTimeStart"));
        }
        return time;
    }

    /**
     * 获取模板并将内容输出到模板
     *
     */
    private String getMailText(EmailParam emailParam) throws IOException, TemplateException {
        // 装载模板
        Template tpl = this.freeMarkerConfigurer.getConfiguration().getTemplate("alertNoticeEmail.ftl");
        // 加入map到模板中 输出对应变量
        return FreeMarkerTemplateUtils.processTemplateIntoString(tpl, emailParam);
    }

    /**
     *
     * <p>Description: 更新结转时间</p>
     * @param type 类型
     * @param time 时间
     * @throws DaoException dao层异常
     */
    private void updateTaskTime(String type, String time) throws DaoException{
        Map<String, Object> params = new HashMap<>();
        params.put("type", type);
        params.put("gatherTimeEnd", time);
        this.entityDao.findByProperty("com.broadtext.message.model.SysMessage.updateTaskTime", params);
    }
}
